<?php
/**
 * Page description
 *
 * @package 
 * @version {: }
 */

/**
 * Class description
 * 
 * @package 
 * @subpackage 
 * @author Author Name <email>
 */
class System_View_Helper{
    /**
     * constant to hold the prefix for the helper classes
     */
    const HELPER_PREFIX = 'System_View_Helper_';
    
    /**
     * holds the model to be manipulated
     * 
     * @var Object - Instance of System_Database_Base
     * @access private
     */
    private $_model;
    
    /**
     * holds an array of System View helper classes to be executed against the current model's data
     * 
     * @var array
     * @access private
     */
    private $_rule_stack = array();
    
    /**
     * holds the data that has been modified by a System_View_Helper_Object
     * 
     * @var array
     * @access private
     */
    private $_dirty_data = array();
    
    /**
     * Class Constructor
     *
     * @param Object $model - Instance of System_Database_Base
     * @param Array $rules - Multi dimensional array containing the rules to manipulate the model data
     * @access public
     * @return null
     */     
    public function __construct($model = false, array $rules = array()){
        if($model){
            $this->setModel($model);
        }
        
        if(count($rules)){
            $this->setRules($rules);
        }
    }
    
    /**
     * sets the model
     *
     * @param Object $model - Instance of System_Database_Base
     * @access public
     * @throws System_View_Exception - if the model is not an instance of System_Database_Base
     * @return Object - System_View_Helper
     */
    public function setModel($model){
        if($model instanceof System_Database_Base){
            $this->_model = $model;
        }else{
            throw new System_View_Exception('You must pass in an object that is an instance of System_Database_Base.');
        }
        
        return $this;
    }
    
    /**
     * sets the rules property stack
     *
     * @param Array $rules - the rules to manipulate the model data. This can be a single System_View_Helper object or an array of System_View_Helper objects that will execute in the order that they were defined.
     * @access public
     * @return Object - System_View_Helper
     */
    public function setRules($rules){
        $this->_rule_stack = $rules;
        
        return $this;
    }
    
    /**
     * resets the state of the class
     *
     * @access public
     * @return Object - System_View_Helper
     */
    public function reset(){
        $this->_model       = false;
        $this->_dirty_data  = array();
        $this->_rule_stack  = array();
        
        return $this;
    }
    
    /**
     * builds the output
     *
     * @access public
     * @return String - The result of the processing from the rules property stack
     */
    public function build(){
        $iter = 0;
        
        /**
         * loop through the rules stack and 
         */
        foreach($this->_rule_stack as $rule_set){
            $obj = new self::HELPER_PREFIX . ucfirst($rule_set['helper']);
            $obj->setModel($this->_model);
                
            if(isset($rule_set['rules'])) $obj->setRules($rule_set['rules']);
            
            /**
             * if this is not he first iteration, set the data and run the process chain method
             * else, run the process method
             */
            if($iter++ > 0){
                $obj->setData($this->_dirty_data)->processChain();
            }else{
                $obj->process();
            }
                 
            $this->_dirty_data = $obj->get('affected');
        }
        
        return $obj->get('processed');
    }
}